<?php
/**
 * LoveDiaryService.php
 * Created on 2020/8/31 18:35
 * Created by 刘小龙 595929049@qq.com
 */

namespace app\xiangji\services;



use app\common\caches\DiaryCache;
use app\common\facades\auth\Auth;
use app\common\helpers\Response;
use app\common\models\LoveAchieve;
use app\common\models\LoveDiary;
use app\Request;
use app\xiangji\exception\BadRequestException;
use app\xiangji\exception\ModelNotFoundException;
use app\xiangji\jobs\AchieveLoveScoreJob;
use app\xiangji\jobs\GiveLoveScoreJob;
use Carbon\Carbon;
use think\App;
use think\facade\Queue;

class LoveDiaryService
{
    const SELF_TAG  = 1;
    const LOVER_TAG = 2;
    private $user;
    private $diaryModel;

    public function __construct(LoveDiary $diaryModel)
    {
        $this->user = Auth::guard('api')->user();
        $this->diaryModel = $diaryModel;
    }

    public function fetch(Request $request)
    {

        $params = $request->get(['page', 'limit', 'date', 'content', 'only']);
        $lover_id = $this->user->lover->lover_id;
        // 日记归属
        if ($params['only'] == self::SELF_TAG){
            $model = $this->diaryModel->where('user_id', '=', $this->user->id);
        }elseif ($params['only'] == self::LOVER_TAG){
            $model = $this->diaryModel->where('user_id', '=', $lover_id);
        }else{
            $model = $this->diaryModel->whereIn('user_id', [$lover_id, $this->user->id]);
        }
        $date = $request->get('date');
        // 如果不存在date则取当前月份,否则取传入的月份
        if (!$date) {
            $month = Carbon::now()->format('Y-m');
        } else {
            $month = date('Y-m',strtotime($date));
        }
        $model = $model->whereMonth('create_time', $month);

        // 月份，默认当前页
        // $month = $request->get('month', Carbon::now()->format('Y-m'));
        // $model = $model->whereMonth('create_time', $month);
        // 内容筛选，暂未启用
        if (isset($params['content']) && !empty($params['content'])){
            $model = $model->where('content', 'like', "%{$params['content']}%");
        }
        // 传入具体天，则当天的日记排最前
        if ($date && date('Y-m-d', strtotime($date)) == $date ){
            if ($params['page'] == 1){
                $model2 = clone $model;
                $this_day_data = $model2
                    ->whereDay('create_time', $params['date'])
                    ->field(['id', 'user_id','mood', 'weather', 'content', 'images', 'labels', 'create_time', 'update_time'])
                    ->select()
                    ->each(function ($item){
                        $item->own = $item->user_id == $this->user->id;
                    })->toArray();
            }
            $model = $model->whereNotBetween('create_time', [Carbon::parse($params['date'])->timestamp, Carbon::parse($params['date'])->addDays(1)->timestamp]);
        }
        $data = $model->order('id', 'desc')
            ->field(['id', 'user_id','mood', 'weather', 'content', 'images', 'labels', 'create_time', 'update_time'])
            ->paginate(['list_rows' => $params['limit'] ?: 10, 'page' => $params['page'] ?: 1])
            ->each(function ($item){
                $item->own = $item->user_id == $this->user->id;
            })->toArray();
        if ($date && date('Y-m-d', strtotime($date)) == $date && $params['page'] == 1){
            $data['data'] = array_merge($this_day_data, $data['data']);
        }
        return $data;
    }

    public function countMonthDiaries(string $month)
    {
        if (!$month) return [];
        $lover_id = $this->user->lover->lover_id;
        $data = $this->diaryModel
            ->whereIn('user_id', [$this->user->id, $lover_id])
            ->whereMonth('create_time', $month)
            ->select();
        $result = [];
        foreach ($data as $diary){
            $date = Carbon::parse($diary->create_time)->format('Y-m-d');
            if (!isset($result[$date])){
                $result[$date] = [
                    'date' => $date,
                    'self' => 0,
                    'lover' => 0
                ];
            }
            if ($diary->user_id == $this->user->id){
                $result[$date]['self'] += 1;
            }
            if ($diary->user_id == $lover_id){
                $result[$date]['lover'] += 1;
            }
        }
        return array_values($result);
    }

    public function create(Request $request)
    {
        //校验字数：文字+表情不超过140
        $preg='/<img.*?\/emoji\/(\d{1,3})\.gif.*?>/is';
        if (mb_strlen(preg_replace($preg, 'q', $request->post('content', ''))) > 140){
            throw new BadRequestException('日记不能超过30个字符');
        }
        if (DiaryCache::getCreateDate($this->user->id) == Carbon::now()->format('Y-m-d')){
            throw new BadRequestException('每日只能创建一篇日记', Response::HTTP_BAD_REQUEST);
        }
        $data = $request->post(['content', 'images', 'labels', 'location', 'weather', 'mood']);
        // 内容安全检测
        $is_safe_content = (new WechatService())->checkText($data['content']);
        if ($is_safe_content['errcode'] != 0){
            throw new BadRequestException('内容含有违法违规内容');
        }
        $data['images'] = $this->resetImage($data['images']);
        // 保存日记
        $diary = $this->user->diaries()->save($data);
        // 发放奖励
        Queue::push(GiveLoveScoreJob::class, ['user_id' => $this->user->id, 'score' => 5, 'scene' => '新增日记奖励'], 'give_love_score');
        // 触发成就
        Queue::push(AchieveLoveScoreJob::class, ['user_id' => $this->user->id, 'type' => LoveAchieve::TYPE_DIARY], 'love_score_achieve');
        return $diary;
    }

    public function update(Request $request, $id)
    {
        //校验字数：文字+表情不超过140
        $preg='/<img.*?\/emoji\/(\d{1,3})\.gif.*?>/is';
        if (mb_strlen(preg_replace($preg, 'q', $request->post('content', ''))) > 140){
            throw new BadRequestException('日记不能超过30个字符');
        }
        $data = $request->put(['content', 'images', 'labels', 'location', 'weather', 'mood']);
        // 内容安全检测
        $is_safe_content = (new WechatService())->checkText($data['content']);
        if ($is_safe_content['errcode'] != 0){
            throw new BadRequestException('内容含有违法违规内容');
        }
        // 图片url处理
        $data['images'] = $this->resetImage($data['images']);
        $diary = $this->user->diaries()->find($id);
        if (!$diary){
            throw new ModelNotFoundException('未找到该日记信息');
        }
        return $diary->save($data);
    }

    private function resetImage(array $images = [])
    {
        if (!$images || count($images) <= 0) return [];
        $url = config('filesystem.disks.aliyun.url');
        $fileService = new FileService();
        foreach ($images as $key => $image){
            if (strpos($image, $url) === false) continue; // 不是正确url
            if (strpos($image, '/temp') === false) continue; // 不是临时文件不需要处理
            $temp_path = str_replace($url.'/', '', $image);
            $real_path = str_replace('temp', 'images', $temp_path);
            $fileService->moveFile($temp_path, $real_path);
            $images[$key] = $url . '/' . $real_path;
        }
        return $images;
    }


    public function delete($id)
    {
        $diary = DiaryCache::get($this->user->id, $id);
        return $diary && $diary->delete();
    }

    public function show($id)
    {
        $lover_id = $this->user->lover->lover_id;
        $diary = $this->diaryModel->whereIn('user_id', [$this->user->id, $lover_id])->find($id);
        if (!$diary){
            throw new ModelNotFoundException('未找到该日记信息');
        }
        return $diary;
    }
}
